<template>
  <div class="login-container" :style="{ background: `url(${bgsPath}) center center/100% 100% no-repeat` }">
    <div class="login-container-form">
      <div class="login-container-hello">欢迎注册</div>
      <div class="login-container-title">保镖人才网管理中心</div>
      <a-form ref="formRef" :model="form" :rules="rules" @keyup.enter="handleSubmit">
        <a-form-item name="username">
          <a-input v-model:value="form.username" autocomplete="off" placeholder="请输入用户名">
            <template v-slot:prefix>
              <UserOutlined style="color: rgba(0, 0, 0, 0.25)" />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item name="password">
          <a-input-password v-model:value="form.password" autocomplete="off" placeholder="请输入密码">
            <template v-slot:prefix>
              <LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
            </template>
          </a-input-password>
        </a-form-item>
        <a-form-item>
          <a-button type="primary" :loading="isLoading" size="large" block @click="handleSubmit()">
            立即注册
          </a-button>
        </a-form-item>
        <a-form-item>
          <a-button type="link" size="large" block @click="$router.replace('/login')">
            已有账号去登录
          </a-button>
        </a-form-item>
      </a-form>
    </div>
  </div>
  <!-- 人脸识别对话框 -->
  <a-modal width="398px" v-model:visible="faceDialogVisible" @cancel="isLoading = false; closeMedia()" :footer="null">
    <div class="faceTitle">人脸录入</div>
    <video ref="video" height="350" width="350" autoplay style="margin: 0 auto;" v-show="!showCanvas"></video>
    <canvas ref="canvas" height="350" width="350" style="margin: 0 auto;" v-show="showCanvas"></canvas>
    <a-button type="primary" style="width: 100%; height: 40px;margin-top: 15px" @click="takePhoto"
      v-show="!showCanvas">拍照</a-button>
    <a-row v-show="showCanvas" :gutter="20" style="margin-top: 15px">
      <a-col :span="11" :offset="1">
        <a-button style="width: 100%;height: 40px;" type="info" @click="showCanvas = false">重拍</a-button>
      </a-col>
      <a-col :span="11">
        <a-button type="primary" :loading="faceLoading" style="width: 100%;height: 40px;" @click="upload">录入</a-button>
      </a-col>
    </a-row>
  </a-modal>
</template>

<script lang="ts" setup>
import { message } from 'ant-design-vue'
import { getCurrentInstance, onUnmounted, reactive, ref, UnwrapRef } from "vue"
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
import request from '@/request'

const { proxy }: any = getCurrentInstance()

// 表单数据
const form = data_form()

const rules = reactive({
  username: [
    {
      required: true,
      message: '请输入用户名',
      trigger: 'change'
    }
  ],
  password: [
    {
      required: true,
      message: '请输入密码',
      trigger: 'change'
    }
  ]
})

const formRef = ref()

/**
 * @desc: 注册提交
 */
const handleSubmit = (): void => {
  formRef.value.validate().then(() => {
    isLoading.value = true
    request.post('is_register', form).then(({ data }: any) => {
      if (data.user) {
        isLoading.value = false
        return message.error('该用户已注册!')
      }
      showFaceDialog()
    })
  })
}

// 背景图片列表
const bgsPath = ref(['/images/41.jpg', '/images/42.jpg', '/images/43.jpg','/images/44.jpg'][Math.floor(Math.random() * 4)])
// 注册按钮的loading状态
const isLoading = ref(false)
// 表单数据
function data_form() {
  const form: UnwrapRef<any> = reactive({
    username: undefined,
    password: undefined
  })
  return form
}

// 录入人脸对话框的显示隐藏
const faceDialogVisible = ref(false)
// 摄像头对象
const mediaTracks = ref()
// canvas显示隐藏
const showCanvas = ref(false)
// 显示人脸对话框
async function showFaceDialog() {
  faceDialogVisible.value = true
  // 等待dom结点渲染完成
  await proxy.$nextTick()
  const constraints = {
    video: { width: 500, height: 500 }
    // audio: true,  // 麦克风
  }
  // 获得video摄像头区域
  const video = proxy.$refs.video
  const promise = navigator.mediaDevices.getUserMedia(constraints)
  promise
    .then((MediaStream) => {
      video.srcObject = MediaStream
      // 保存stop关闭摄像头的方法
      mediaTracks.value =
        typeof (MediaStream as any).stop === 'function'
          ? MediaStream
          : MediaStream.getTracks()[0]
      video.play()
    })
    .catch((e) => {
      faceDialogVisible.value = false
      isLoading.value = false
      message.error('获取摄像头权限失败!')
    })
}
// 拍照
function takePhoto() {
  // 获得Canvas对象
  const video = proxy.$refs.video
  const canvas = proxy.$refs.canvas
  const ctx = canvas.getContext('2d')
  ctx.drawImage(video, 0, 0, 350, 350)
  showCanvas.value = true
}
// 关闭摄像头
function closeMedia() {
  mediaTracks.value && mediaTracks.value.stop()
}
// 组件卸载时调用关闭摄像头方法
onUnmounted(() => {
  closeMedia()
})
// 人脸验证按钮loading
const faceLoading = ref(false)
// 人脸验证
async function upload() {
  faceLoading.value = true
  const canvas = proxy.$refs.canvas
  const base64 = canvas.toDataURL().slice(22)
  const { data } = await request.post('/upload/base64', { base64 })
  await request.post('register', { photo: data.path, username: form.username, pwd: form.password, roles: '管理员' })
  message.success('注册成功!')
  proxy.$router.replace('/login')
}
</script>
<style lang="scss" scoped>
.faceTitle {
  font-size: 20px;
  margin-top: -10px;
  margin-bottom: 10px;
}

.login-container {
  width: 100vw;
  height: 100vh;
  
  .login-container-form {
    position: absolute;
    left: 50%;
    top: 50%;
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    width: 540px;
    max-width: 100%;
    padding: 40px 70px;
    overflow: hidden;
    background-color: rgba(255, 255, 255, 0.489);
    border-radius: 5px;
    -webkit-box-shadow: 0 2px 4px rgb(0 0 0 / 12%), 0 0 6px rgb(0 0 0 / 4%);
    box-shadow: 0 2px 4px rgb(0 0 0 / 12%), 0 0 6px rgb(0 0 0 / 4%);
    text-align: center;

    .login-container-hello {
      font-size: 26px;
      line-height: 1;
      color: #333;
      margin-bottom: 10px;
    }

    .login-container-title {
      font-size: 14px;
      line-height: 1;
      color: rgb(67, 56, 56);
      margin-bottom: 26px;
    }

    ::v-deep .ant-form-item {
      margin-bottom: 0;

      .ant-form-item-explain {
        margin-top: -24px;
        text-align: left;
      }

      .ant-input-affix-wrapper {
        margin-bottom: 25px;
        border: 1px solid #dcdfe6;
        border-radius: 5px;
        color: #454545;
        -webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
        transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
        height: 50px;

        .ant-input {
          padding-left: 10px;
        }
      }
    }

    .ant-btn-lg {
      height: 48px;
      border-radius: 5px;
    }
  }
}
</style>